package com.ruoyi.configManage.util;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.StorageClass;
import com.ruoyi.configManage.mapper.OssConfigMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Objects;
import java.util.UUID;

/**
 * aliYun:
 * endpoint: https://oss-cn-chengdu.aliyuncs.com/
 * accessKeyId: LTAI5t79GMMHtnUTFqjUyU1F
 * accessKeySecret: QVTuJFMTMv8WqhExtu91lt7REPC1Rg
 * bucketName: fuhewenchuang
 * objectName: image/
 * url: https://fuhewenchuang.oss-cn-chengdu.aliyuncs.com/
 * <p>
 * <p>
 * className AliOSSUtil
 * author cx
 * date 2023/7/17 001715:20
 * describe 1.0
 **/
@Component
@Slf4j
public class AliOSSUtil {
    @Resource
    private OssConfigMapper aliyunOssConfigMapper;

    //public static void main(MultipartFile file) throws IOException {
    //    String url = new AliOSSUtil().uploadFile(file.getInputStream(), file.getOriginalFilename());
    //}
    public String uploadFile(InputStream inputStream, String filename) {
        String accessKeyId = aliyunOssConfigMapper.selectOneData("accessKeyId");
        String accessKeySecret = aliyunOssConfigMapper.selectOneData("accessKeySecret");
        String objectName = aliyunOssConfigMapper.selectOneData("objectName");
        String endpoint = aliyunOssConfigMapper.selectOneData("endpoint");
        String bucketName = aliyunOssConfigMapper.selectOneData("bucketName");
        String url = aliyunOssConfigMapper.selectOneData("url");
        String objectUrl = objectName + System.currentTimeMillis() + filename.substring(filename.lastIndexOf("."));
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectUrl, inputStream);

            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            metadata.setObjectAcl(CannedAccessControlList.PublicRead);
            putObjectRequest.setMetadata(metadata);
            // 上传文件。
            ossClient.putObject(putObjectRequest);
            //得到上传之后的文件地址
            //https://bucketname.endpoint/objectnane  https://upload-demo-liu.oss-cn-hangzhou.aliyuncs.com
            String fileUrl = url + objectUrl;
            log.info("上传之后的文件路径" + fileUrl);
            return fileUrl;

        } catch (OSSException oe) {
            log.info("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.info("Error Message:" + oe.getErrorMessage());
            log.info("Error Code:" + oe.getErrorCode());
            log.info("Request ID:" + oe.getRequestId());
            log.info("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.info("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.info("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        return "上传失败";
    }

    private static final String UPLOAD_FOLDER = "/home/ruoyi/uploadPath/";
    public  String uploadLocalFile(MultipartFile file) throws IOException {
        if (file == null || file.isEmpty()) {
            return "上传失败：请选择文件";
        }
        try {
            byte[] bytes = file.getBytes();
            Path uploadPath = Paths.get(UPLOAD_FOLDER);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            // 使用UUID生成唯一文件名，防止文件覆盖
            String fileName = UUID.randomUUID() + "." + getFileExtension(file.getOriginalFilename());
            Path path = uploadPath.resolve(Objects.requireNonNull(file.getOriginalFilename()));
            // 使用StandardCopyOption.REPLACE_EXISTING确保文件可以被替换（可选，根据需求决定）
            Files.write(path, bytes);
            return UPLOAD_FOLDER + path;
        } catch (IOException e) {
            // 使用日志记录异常，而不是打印堆栈跟踪（假设已有日志框架）
            log.error("文件上传失败", e);
            return "上传失败：发生IO异常";
        }
    }

    private static String getFileExtension(String fileName) {
        if (fileName == null || fileName.lastIndexOf(".") == -1) {
            return ""; // 如果没有扩展名，返回空字符串或默认扩展名
        }
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    /**
     * 将 MultipartFile 转换为 File 对象（不保存到本地文件）
     *
     * @param multipartFile MultipartFile 对象
     * @return 转换后的 File 对象
     * @throws IOException 如果发生 I/O 异常
     */
    public File convertToFileInMemory(MultipartFile multipartFile) throws IOException {
        File file = File.createTempFile("temp", null); // 使用临时文件
        try {
            Files.copy(multipartFile.getInputStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            throw new IOException("Failed to convert MultipartFile to File", e);
        }
        return file;
    }
}
